/*
 * Copyright (c) China Telecom Cloud Technology Co., Ltd. 2024-2025. All rights reserved.
 */
#ifndef KVSTORAGE_CLIENT_H
#define KVSTORAGE_CLIENT_H

#include "FsStrategy.h"
#include "Segment.h"

#if defined(USE_THREEFS)
#include "ThreeFsStrategy.h"
#elif defined(USE_POSIX)
#include "PosixStrategy.h"
#elif defined(USE_LUSTRE)
#include "LustreStrategy.h"
#endif

#include <fcntl.h>
#include <memory>
#include <mutex>
#include <unistd.h>
#include <unordered_map>

class KVStorageClient {
public:
    static KVStorageClient &getInstance() {
        static KVStorageClient instance;  // 默认构造函数
        return instance;
    }

    /**
     *! @brief  初始化存储系统环境
     * 
     * @param type  
     * @param path 
     * @param addr 
     * @param mountPath 
     */
    void init(FileSystem type, 
              std::string path, 
              void *addr,
              std::string mountPath
            );

    /**
     *! @brief 读取目标文件数据，写入到指定共享内存，支持偏移量设置
     * 
     * @param objId      segmentId, 用于生成持久化文件名
     * @param segment    写入目标Segment
     * @param srcOffset  待读取数据在segment内部偏移
     * @param dstOffset  待读取数据在持久化文件中的偏移 
     * @param length     读取数据的长度
     * 
     * @return int32_t   成功返货0否则返回具体错误码
     */
    int32_t get(const std::string &objId, 
                const Segment &segment,
                const uint64_t srcOffset, 
                const uint64_t dstOffset,
                const uint64_t length) noexcept;


    /**
     *! @brief 将Segment中中的数据存储到具体的文件中
     * 
     * @param objId      segmentId, 用于生成持久化文件名
     * @param segment    读取原Segment
     * @param srcOffset  待读取数据在segment内部偏移
     * @param dstOffset  待读取数据在持久化文件中的偏移 
     * @param length     读取数据的长度
     * 
     * @return int32_t   成功返货0否则返回具体错误码
     */
    int32_t put(const std::string &objId, 
                const Segment &segment,
                const uint64_t srcOffset, 
                const uint64_t dstOffset,
                const uint64_t length
            ) noexcept;


    /**
     *! @brief 删除文件
     * 
     * @param objId    删除objId对应的KV Cache文件
     * 
     * @return int32_t 成功返货0否则返回具体错误码
     */
    int32_t remove(const std::string &objId) noexcept;

    /*
     * 检查objId对应的文件是否存在，objId和tpNum共同拼接成文件名
     * @return 文件存在返回true，文件不存在返回false
     */

    /**
     *! @brief 判断某个对应的KV Cache文件是否存在
     * 
     * @param objId  segmentId
     * 
     * @return bool
     */
    bool isExist(const std::string &objId) noexcept;

private:
    FileSystem fsType;
    std::unique_ptr<FsStrategy> strategy;

    bool inited = false;   // 是否已经初始化

    KVStorageClient()  = default;
    ~KVStorageClient() = default;

    // 隐藏构造函数, 使用单例模式
    KVStorageClient(const KVStorageClient &single) = delete;

    // 禁用赋值构造函数
    const KVStorageClient &operator=(const KVStorageClient &single) = delete;
};

#endif // KVSTORAGE_CLIENT_H
